package cn.seaboot.admin.upload.utils;

import cn.seaboot.commons.exception.BizException;
import cn.seaboot.commons.file.FilenameUtils;
import cn.seaboot.commons.file.MimeUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Locale;

/**
 * 可能会被使用到的文件上传工具
 * <p>
 * 针对不同业务场景，对请求域中的文件，设计了不同的获取方法，使用过程中，需要根据业务需求，选用不同函数。
 * <p>
 * 函数以效率优先，因此存在一定的代码冗余，Found duplicate code。
 *
 * @author Mr.Css
 * @version 2020-11-23 18:12   限制用户上传用的文件名（旧版本中，如果只上传1个文件，不限制文件名）
 */
public class UploadUtils {
    private UploadUtils() {
    }

    /**
     * MultipartRequestConverter 请求转换器
     */
    private static MultipartRequestConverter converter = new DefaultMultipartRequestConverter();

    /**
     * MultipartFileValidator 文件有效性验证
     */
    private static MultipartFileValidator validator = new DefaultMultipartFileValidator();

    /**
     * Get extension form originalFilename first, if originalFilename is null or haven't extension,
     * try get extension by mime type, if field also, throw a FileException.
     *
     * @param multipartFile uploaded file
     * @return extension
     */
    public static String getExtension(MultipartFile multipartFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        if (originalFilename != null) {
            // if contain original file name.
            return FilenameUtils.getExtension(originalFilename);
        } else {
            // 讲道理，上传文件，不应该没有文件名
            throw new IllegalArgumentException("not content file name!");
        }
    }

    /**
     * 按照名字，获取请求域中的一个文件，如果存在其它文件，则直接忽略。
     *
     * @param request  -
     * @param fileName 文件名
     * @return -
     */
    public static MultipartFile getMultipartFile(HttpServletRequest request, String fileName) {
        if (isMultipartContent(request)) {
            MultipartHttpServletRequest multiRequest = converter.convertToMultipartRequest(request);
            if (multiRequest != null) {
                MultipartFile file = multiRequest.getFile(fileName);
                if (validator.isValid(file)) {
                    return file;
                }
            }
        }
        return null;
    }

    /**
     * 获取请求域中全部同名文件
     *
     * @param request  -
     * @param fileName 文件名
     * @return -
     */
    public static List<MultipartFile> getMultipartFileList(HttpServletRequest request, String fileName) {
        if (isMultipartContent(request)) {
            MultipartHttpServletRequest multiRequest = converter.convertToMultipartRequest(request);
            if (multiRequest != null) {
                List<MultipartFile> fileList = multiRequest.getFiles(fileName);
                fileList.removeIf(file -> !validator.isValid(file));
                return fileList.isEmpty() ? null : fileList;
            } else {
                return null;
            }
        }
        return null;
    }

    /**
     * 图片地址拼接，多图片地址拼接，一般设置多个图片槽而不使用此函数
     *
     * @param oldPath 原有的图片地址
     * @param newPath 新的图片地址
     * @return 需要保存到数据库的图片地址
     */
    public static String concatPath(String oldPath, String newPath) {
        if (newPath == null || newPath.isEmpty()) {
            return oldPath;
        } else if (oldPath == null || oldPath.isEmpty()) {
            return newPath;
        } else {
            return oldPath + "," + newPath;
        }
    }

    /**
     * 判断是不是request请求
     *
     * @param request request
     * @return boolean
     * @see org.springframework.web.multipart.support.StandardServletMultipartResolver
     */
    public static boolean isMultipartContent(HttpServletRequest request) {
        return request.getContentType().toLowerCase(Locale.ENGLISH).startsWith("multipart/");
    }

    // any getter and setter ------------------------------------------

    public static MultipartRequestConverter getConverter() {
        return converter;
    }

    public static void setConverter(MultipartRequestConverter converter) {
        UploadUtils.converter = converter;
    }

    public static MultipartFileValidator getValidator() {
        return validator;
    }

    public static void setValidator(MultipartFileValidator validator) {
        UploadUtils.validator = validator;
    }

    // any getter and setter ------------------------------------------
}
